﻿#include "mainwindow.h"
#include "formatpanel.h"  
#include <QWidget>
#include <QApplication>
#include <QObject>
#include <QDebug>
#include <QMessageBox>
#include <QTextCodec>

MainWindow::MainWindow(QWidget* parent)
	: QMainWindow(parent)
{
	initUI();
	initController();
	setWindowTitle(tr("word"));
	setMinimumSize(1024, 768);
	resize(1200, 800);
}

void MainWindow::initUI()
{
	m_menubar = new MenuBar(this);
	setMenuBar(m_menubar); 
	m_formatController = new FormatController(this);

	QWidget* centralWidget = new QWidget(this);
	QVBoxLayout* mainLayout = new QVBoxLayout(centralWidget);
	mainLayout->setContentsMargins(0, 0, 0, 0);
	mainLayout->setSpacing(0);

	m_ribbon = new RibbonToolbar(this);
	mainLayout->addWidget(m_ribbon);
	m_ribbon->setFixedHeight(130);

	m_documenttabs = new DocumentTabWidget(this);
	m_documenttabs->setFixedHeight(40);
	m_documenttabs->setStyleSheet(R"(
        QTabBar::tab {
            padding: 8px 16px;
            margin: 0 2px;
        }
        QTabBar::tab:selected {
            border-bottom: 2px solid #0078D7;
        }
    )");
	mainLayout->addWidget(m_documenttabs);

	m_splitter = new QSplitter(Qt::Horizontal);
	m_splitter->setObjectName("MainSplitter"); 
	m_splitter->setChildrenCollapsible(false);

	EditorWidget* firstEditor = new EditorWidget(this);
	firstEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	m_editors.append(firstEditor);
	m_splitter->addWidget(firstEditor);
	m_splitter->setStretchFactor(0, 8);

	m_sidebar = new FormatPanel(this);
	QWidget* sidebarWidget = m_sidebar->widget();
	m_splitter->addWidget(sidebarWidget);
	m_splitter->setStretchFactor(1, 2);
	sidebarWidget->setMinimumWidth(250);

	mainLayout->addWidget(m_splitter);

	setCentralWidget(centralWidget);
	setWindowState(Qt::WindowMaximized);

	QString firstKey = QString::number(reinterpret_cast<quint64>(firstEditor));
	m_documenttabs->addDocumentTab(tr("文档 1"), firstKey, false);

	connect(m_menubar, &MenuBar::newDocumentTriggered,
		this, &MainWindow::addNewDocumentTab);
	connect(m_documenttabs, &DocumentTabWidget::tabSwitched,
		this, &MainWindow::onTabSwitched);
	connect(m_menubar, &MenuBar::saveDocumentTriggered,
		this, &MainWindow::onSaveDocument);
	connect(m_menubar, &MenuBar::saveAsDocumentTriggered,
		this, &MainWindow::onSaveAsDocument);
	connect(m_menubar, &MenuBar::openDocumentTriggered,
		this, &MainWindow::onOpenDocument);
	connect(m_documenttabs, &DocumentTabWidget::closeTabRequested,
		this, &MainWindow::onTabCloseRequested);
	connect(m_ribbon, &RibbonToolbar::newRequested, this, &MainWindow::addNewDocumentTab);
	connect(m_ribbon, &RibbonToolbar::saveRequested, this, &MainWindow::onSaveDocument);
	connect(m_ribbon, &RibbonToolbar::openRequested, this, &MainWindow::onOpenDocument);
}

void MainWindow::initController()
{
	m_formatController->setRibbonToolbar(m_ribbon);      
	m_formatController->setFormatPanel(m_sidebar);       
	m_formatController->setMenuBar(m_menubar);
	m_formatController->setActiveEditor(m_editors[0]);   
	m_formatController->initConnections();               
}

void MainWindow::addNewDocumentTab()
{
	EditorWidget* newEditor = new EditorWidget(this);
	newEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
	m_editors.append(newEditor);

	QString key = QString::number(reinterpret_cast<quint64>(newEditor));
	int tabIndex = m_documenttabs->addDocumentTab(QString(tr("文档 %1")).arg(m_editors.count()), key, false);
	Q_UNUSED(tabIndex);
	m_filePaths[key] = "";  
}

void MainWindow::onTabSwitched(int index)
{
	if (index >= 0 && index < m_editors.count())
	{
		QSplitter* splitter = qobject_cast<QSplitter*>(centralWidget()->findChild<QSplitter*>());
		if (splitter) 
		{
			QList<int> sizes = splitter->sizes();
			splitter->replaceWidget(0, m_editors[index]);
			splitter->setSizes(sizes);
		}
		m_formatController->setActiveEditor(m_editors[index]);
	}
}


MainWindow::~MainWindow()
{
	qDeleteAll(m_editors);
	m_editors.clear();

	if (m_documenttabs) 
	{
		delete m_documenttabs;
		m_documenttabs = nullptr; 
	}
}

void MainWindow::onSaveDocument()
{

	int currentTabIndex = m_documenttabs->currentIndex();
	if (currentTabIndex < 0 || currentTabIndex >= m_editors.count())
	{
		QMessageBox::warning(this, tr("错误"),tr("未找到当前编辑区"));
		return;
	}
	EditorWidget* currentEditor = m_editors[currentTabIndex];
	QString editorKey = QString::number(reinterpret_cast<quint64>(currentEditor));
	struct FormatOption 
	{
		QString name;       
		QString suffix;     
		QString filter;     
	};
	QList<FormatOption> formats = 
	{
		{"纯文本", "txt", "纯文本 (*.txt)"},
		{"富文本", "rtf", "富文本 (*.rtf)"},
		{"网页", "html", "网页文件 (*.html *.htm)"}
	};

	QString filterStr;
	for (const auto& fmt : formats) 
	{
		filterStr += fmt.filter + ";;";
	}
	filterStr.chop(2); 

	QString defaultDir = m_filePaths.contains(editorKey)
		? QFileInfo(m_filePaths[editorKey]).dir().path()
		: QDir::homePath();
	QString defaultName = QString(tr("文档%1")).arg(currentTabIndex + 1);

	QString filePath = QFileDialog::getSaveFileName
	(
		this,
		"另存为",
		QDir(defaultDir).filePath(defaultName),
		filterStr
	);

	if (filePath.isEmpty()) return; 

	QString selectedSuffix;
	QFileInfo fileInfo(filePath);
	QString userSuffix = fileInfo.suffix().toLower();
	bool formatMatched = false;
	for (const auto& fmt : formats) 
	{
		if (userSuffix == fmt.suffix) 
		{
			selectedSuffix = fmt.suffix;
			formatMatched = true;
			break;
		}
	}
	if (!formatMatched) 
	{
		selectedSuffix = formats[0].suffix;
		filePath += "." + selectedSuffix;
	}
	bool saveSuccess = false;
	QString content = currentEditor->getDocumentContent(); 
	QFile file(filePath);
	if (file.open(QIODevice::WriteOnly | QIODevice::Text)) 
	{
		QTextStream out(&file);
		switch (selectedSuffix.at(0).toLatin1()) 
		{ 
		case 't': 
			out << currentEditor->toPlainText(); 
			saveSuccess = true;
			break;
		case 'r': 
			out << currentEditor->toRtf(); 
			saveSuccess = true;
			break;
		case 'h': 
			out << content; 
			saveSuccess = true;
			break;
		default:
			QMessageBox::warning(this, "错误", "不支持的格式");
		}
		file.close();
	}

	if (saveSuccess)
	{
		m_filePaths[editorKey] = filePath;
		m_fileFormats[editorKey] = selectedSuffix;
		m_documenttabs->setTabText(currentTabIndex, fileInfo.fileName());
		currentEditor->setModified(false);
		m_documenttabs->updateTabModifiedState(currentTabIndex, false);
	}
	else
	{
		QMessageBox::critical(this, "失败", "无法保存文件，请检查路径权限");
	}
}

void MainWindow::onSaveAsDocument()
{
	int currentTabIndex = m_documenttabs->currentIndex();
	if (currentTabIndex < 0 || currentTabIndex >= m_editors.count())
	{
		QMessageBox::warning(this, "错误", "未找到当前编辑区");
		return;
	}

	EditorWidget* currentEditor = m_editors[currentTabIndex];
	QString key = QString::number(reinterpret_cast<quint64>(currentEditor));

	QString filePath = QFileDialog::getSaveFileName
	(
		this,
		"另存为",
		QDir::homePath(),
		"Word 文档 (*.docx);;所有文件 (*)"
	);

	if (filePath.isEmpty())
		return; 

	if (!filePath.endsWith(".docx", Qt::CaseInsensitive))
		filePath += ".docx";

	if (saveToFile(currentEditor, filePath))
	{
		m_filePaths[key] = filePath;
		QFileInfo fileInfo(filePath);
		m_documenttabs->setTabText(currentTabIndex, fileInfo.fileName());
	}
}

bool MainWindow::saveToFile(EditorWidget* editor, const QString& filePath)
{
	if (!editor)
		return false;

	QTextDocument* doc = editor->document();
	QFile file(filePath);
	if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
		return false;

	QTextStream out(&file);
	out << doc->toHtml(); 
	file.close();
	return true;

}

void MainWindow::onOpenDocument()
{
	QString filter = "支持的文件 (*.txt *.rtf *.html *.htm);;纯文本 (*.txt);;富文本 (*.rtf);;网页文件 (*.html *.htm)";
	QString filePath = QFileDialog::getOpenFileName
	(
		this,
		"打开文件",
		QDir::homePath(),
		filter
	);

	if (filePath.isEmpty()) return;

	EditorWidget* newEditor = new EditorWidget(this);
	newEditor->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

	if (!loadFileToEditor(filePath, newEditor))
	{
		delete newEditor;
		return;
	}

	m_editors.append(newEditor);
	int newIndex = m_editors.count() - 1;

	QFileInfo fileInfo(filePath);
	QString key = QString::number(reinterpret_cast<quint64>(newEditor));
	m_documenttabs->addDocumentTab(fileInfo.fileName(), key,false);

	m_filePaths[key] = filePath;
	m_fileFormats[key] = fileInfo.suffix().toLower();

	m_documenttabs->setCurrentIndex(newIndex);
	onTabSwitched(newIndex); 
	newEditor->setModified(false);
}

bool MainWindow::loadFileToEditor(const QString& filePath, EditorWidget* editor)
{
	QString content = readFileWithEncoding(filePath);
	if (content.isEmpty())
	{
		QMessageBox::critical(this, "错误", "无法读取文件");
		return false;
	}

	QFileInfo fileInfo(filePath);
	QString suffix = fileInfo.suffix().toLower();
	if (suffix == "txt")
		editor->setPlainText(content);
	else if (suffix == "html" || suffix == "htm")
		editor->setHtml(content);
	else if (suffix == "rtf")
		editor->document()->setHtml(content);
	return true;
}

QString MainWindow::readFileWithEncoding(const QString& filePath)
{
	QFile file(filePath);
	if (!file.open(QIODevice::ReadOnly))
		return "";

	QByteArray data = file.readAll();
	file.close();

	QTextCodec* utf8Codec = QTextCodec::codecForName("UTF-8");
	QString utf8Str = utf8Codec->toUnicode(data);
	if (utf8Str.toUtf8() == data)
		return utf8Str;

	QTextCodec* gbkCodec = QTextCodec::codecForName("GBK");
	QString gbkStr = gbkCodec->toUnicode(data);
	if (gbkCodec->fromUnicode(gbkStr) == data)
		return gbkStr;

	if (data.startsWith("\xef\xbb\xbf"))
		return utf8Codec->toUnicode(data.mid(3));

	return utf8Str;
}

void MainWindow::onTabCloseRequested(int index, const QString& key)
{
	EditorWidget* editor = getEditorByKey(key);
	if (!editor) return;
	qDebug() << editor->isModified();
	if (editor->isModified()) 
	{
		QMessageBox msgBox(this);
		msgBox.setWindowTitle("提示");
		msgBox.setText("文档已修改，请先手动保存！");
		msgBox.setIcon(QMessageBox::Warning);
		msgBox.setStandardButtons(QMessageBox::Ok);
		msgBox.exec();
		return;
	}

	doCloseTab(index, key, editor);
}

void MainWindow::doCloseTab(int index, const QString& key, EditorWidget* editor)
{
	QList<EditorWidget*> remainingEditors = m_editors;
	remainingEditors.removeAt(index);
	delete editor;

	m_editors.clear();
	m_filePaths.clear();
	m_fileFormats.clear();
	m_documenttabs->clear();

	QMetaObject::invokeMethod(this, [=]()
		{
		for (int i = 0; i < remainingEditors.count(); ++i) 
		{
			EditorWidget* editor = remainingEditors[i];
			m_editors.append(editor);
			QString newKey = QString::number(reinterpret_cast<quint64>(editor));

			QString title = m_filePaths.contains(newKey)
				? QFileInfo(m_filePaths[newKey]).fileName()
				: QString("文档 %1").arg(i + 1);           

			m_documenttabs->addDocumentTab(title, newKey, false); 

			if (m_filePaths.contains(newKey)) 
				m_filePaths[newKey] = m_filePaths[newKey];
		}
		if (!m_editors.isEmpty()) 
		{
			m_documenttabs->setCurrentIndex(m_editors.count() - 1);
			onTabSwitched(m_editors.count() - 1);
		}
		}, Qt::QueuedConnection); 
}

EditorWidget* MainWindow::getEditorByKey(const QString& key)
{
	quint64 ptrValue = key.toULongLong();
	return reinterpret_cast<EditorWidget*>(ptrValue);
}

